package org.example.designmodel.forkjoin;

import java.util.Arrays;
import java.util.concurrent.RecursiveTask;

/**
 * 归并排序任务
 */
public class MergeTask extends RecursiveTask<int[]> {

    private int[] nums;
    private int sourceLen;

    public MergeTask(int[] nums) {
        this.nums = nums;
        this.sourceLen = nums.length;
    }

    @Override
    protected int[] compute() {
        if (sourceLen > 2) {
            int mid = sourceLen / 2;
            int[] ints = Arrays.copyOfRange(nums, 0, mid);
            MergeTask task1 = new MergeTask(ints);
            int[] range = Arrays.copyOfRange(nums, mid, sourceLen);
            MergeTask task2 = new MergeTask(range);

            task1.fork();
            task2.fork();

            return joinInts(task1.join(), task2.join());
        } else {
            if (sourceLen == 1 || nums[0] <= nums[1]) {
                return nums;
            } else {
                int[] targets = new int[2];
                targets[0] = nums[1];
                targets[1] = nums[0];
                return targets;
            }
        }
    }

    private static int[] joinInts(int array1[], int array2[]) {
        int destInts[] = new int[array1.length + array2.length];
        int array1Len = array1.length;
        int array2Len = array2.length;
        int destLen = destInts.length;

        // 只需要以新的集合destInts的长度为标准，遍历一次即可
        for (int index = 0, array1Index = 0, array2Index = 0; index < destLen; index++) {
            int value1 = array1Index >= array1Len ? Integer.MAX_VALUE : array1[array1Index];
            int value2 = array2Index >= array2Len ? Integer.MAX_VALUE : array2[array2Index];
            // 如果条件成立，说明应该取数组array1中的值
            if (value1 < value2) {
                array1Index++;
                destInts[index] = value1;
            }
            // 否则取数组array2中的值
            else {
                array2Index++;
                destInts[index] = value2;
            }
        }

        return destInts;
    }
}
